﻿using System;
using System.ComponentModel;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Repository;
using Pipo.AeExtensions;
using Pipo.LblGenExtensions;

namespace MECUITMPLTLIB {
     
    public  partial class AeFrmUiTemplate:XtraForm{
        
        protected  string Cs;
        protected string Branchcode;
        protected string Usercode;
        
     protected ENumFmMode FmMode = ENumFmMode.View;
        protected AeReturnvalue Aereturnvalue;
        protected int Pkid;
        protected string Pkcode;
        protected Object MainEntity;

        private bool _aeUseReadOnlyPropertyWhenLocking = true;
        private bool _aeUsePkCode = true;
        private bool _aeUseAutoUpperCasing = true;
        private string _aeLookupNullDisplay = " ";

        protected AeFrmUiTemplate(){
            InitializeComponent();
        }
        
        protected  virtual  void MethodUpperCase(){
            for (int index = 0; index < this.layoutControl1.Controls.Count; index++){
                var control = this.layoutControl1.Controls[index];
                Type t = control.GetType();
                if (t.IsAssignableFrom(typeof (TextEdit)) || 
                    t.IsAssignableFrom(typeof (LookUpEdit)) || 
                    t.IsAssignableFrom(typeof (SpinEdit)) ||
                    t.IsAssignableFrom(typeof (CalcEdit)) || 
                    t.IsAssignableFrom(typeof (ComboBoxEdit)) ||
                    t.IsAssignableFrom(typeof(MemoEdit)))
                {
                     TextEdit be =  (TextEdit) control;
                    if (be.Name.Contains("_ic_")){
                        continue;
                    }
                    be.Properties.CharacterCasing = CharacterCasing.Upper;
                }
            }
        }
        private void MethodSetLookupNullEditValueDisplay(){
              for (int index = 0; index < this.layoutControl1.Controls.Count; index++){
                var control = this.layoutControl1.Controls[index];
                Type t = control.GetType();
                if (
                    t == typeof(LookUpEdit) || 
                    t == (typeof (ComboBoxEdit)) )
                {
                     LookUpEdit be =  (LookUpEdit) control;
                    if (be.Name.Contains("_ae_")){
                        be.Properties.NullText = AeLookupNullDisplay;
                    }
                    
                }
            }
        } 
        protected virtual void MethodStartup(){
              //StartupProcedure
              //Thisiswherelookupdata is fetched
        }

        public string AeLookupNullDisplay{
            get{
                return _aeLookupNullDisplay;
            }
            set{
                _aeLookupNullDisplay = value;
            }
        }
        public bool AeUseAutoUpperCasing{
            get{
                return _aeUseAutoUpperCasing;
            }
            set{
                _aeUseAutoUpperCasing = value;
            }
        }
        public bool AeUsePkCode{
            get{
                return _aeUsePkCode;
            }
            set{
                _aeUsePkCode = value;
            }
        }
        public bool AeUseReadOnlyPropertyWhenLocking{
            get{
                return _aeUseReadOnlyPropertyWhenLocking;
            }
            set{
                _aeUseReadOnlyPropertyWhenLocking = value;
            }
        }

        public virtual void MethodNewEntityProcedure(){
            if (DesignMode) return;
                MethodClearForm();
                FmMode= ENumFmMode.New;
               
        }
        public AeReturnvalue ShowmetoAdd(){
                FmMode = ENumFmMode.New;
                Aereturnvalue.Cancelled = true;
                ShowDialog();
                return Aereturnvalue;
            }

        public AeReturnvalue ShowmetoEdit(int pkid){
            _aeUsePkCode = false;
            Pkid = pkid;
            FmMode = ENumFmMode.View;
            Aereturnvalue.Cancelled = true;
            ShowDialog();
            return Aereturnvalue;
        }
        public AeReturnvalue ShowmetoEdit(string pkcode){
            _aeUsePkCode = true;
            Pkcode = pkcode;
            FmMode = ENumFmMode.View;
            Aereturnvalue.Cancelled = true;
            ShowDialog();
            return Aereturnvalue;
        }
        public AeReturnvalue ShowmetoEdit(object pkvalue){
            if (pkvalue is string) return ShowmetoEdit((string) pkvalue);
            if (pkvalue is int) return ShowmetoEdit((int) pkvalue);
            throw new NotImplementedException();
        }

        protected virtual void AeFrmUiTemplateLoad(object sender,EventArgs e){
            if (DesignMode) return;
            if (AeUseAutoUpperCasing) MethodUpperCase();
            MethodSetLookupNullEditValueDisplay();
        }

        private void AeFrmUiTemplateShown(object sender,EventArgs e){
            if (DesignMode) return;
            MethodStartup();
            switch (FmMode){
                case ENumFmMode.New:
                    MethodView(true, false);
                    MethodNewEntityProcedure();
                    break;
                case ENumFmMode.View:
                    MethodView(true);
                    break;
                case ENumFmMode.Edit:
                    MethodViewforEdit();
                    break;
                case ENumFmMode.Delete:
                    throw new ArgumentOutOfRangeException();
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }

        private void AeFrmUiTemplateFormClosing(object sender,FormClosingEventArgs e) {
        if (DesignMode) return;
        }
        private void AeFrmUiTemplateFormClosed(object sender,FormClosedEventArgs e) {
        if (DesignMode) return;
        }

        public void BtneditItemClick(object sender,DevExpress.XtraBars.ItemClickEventArgs e) {
            FmMode = ENumFmMode.Edit;
            MethodAllowEdit(true);
          
        }
        private void BtnsaveItemClick(object sender,DevExpress.XtraBars.ItemClickEventArgs e){
            MethodSave();
        }

        private void MethodSave(){
          if (!MethodValidate()){
                AskUser.PopupValidationError("Please check the erros before saving.");
                return;
            }

            try{
                MethodLoadControlValuesToObjectsForSaving();

                BackgroundWorker bgsave = new BackgroundWorker();
                bgsave.DoWork += MainEntityBackgroundSaveDoWork;
                bgsave.RunWorkerCompleted += MainEntityBackgroundSaveWorkCompleted;
                btnsave.Enabled = false;
                btncancel.Enabled = false;
                btnclose.Enabled = false;
                MethodAllowEdit(false);
                barEditItem1.EditValue = Properties.Resources.facebookindicator;
                barStaticItem1.Caption = "Saving";
                bgsave.RunWorkerAsync(MainEntity);
            } catch (Exception ex){

                MessageBox.Show(ex.Message);
            }
        }

        protected virtual void MainEntityBackgroundSaveWorkCompleted(object sender, RunWorkerCompletedEventArgs e){
               try{
                if (e.Cancelled){
                    btncancel.Enabled = true;
                    btnedit.Enabled = false;
                    btnclose.Enabled = true;
                    MethodAllowEdit(true);
                    barEditItem1.EditValue = null;
                    barStaticItem1.Caption = "Cancelled";
                    return;
                }
                if (e.Error != null){
                    btncancel.Enabled = true;
                    btnedit.Enabled = false;
                    btnclose.Enabled = true;
                    MethodAllowEdit(true);
                    barEditItem1.EditValue = null;
                    barStaticItem1.Caption = "Save Failed.";
                    //ErrorHandler.GetUserMessage(e.Error);
                    AskUser.PopupSystemError(ErrorHandler.GetUserMessage(e.Error), "Problem encountered");
                    return;
                }
                if (e.Result == null){
                    btncancel.Enabled = true;
                    btnedit.Enabled = false;
                    btnclose.Enabled = true;
                    MethodAllowEdit(true);
                    barEditItem1.EditValue = null;
                    AskUser.PopupSystemError("There was a problem saving.", "Problem encountered");
                    barStaticItem1.Caption = "Save Failed.";
                    return;
                }
                //Saved!
                MainEntity = e.Result;
                MethodDispayMainEntityToControls();
                Aereturnvalue.Cancelled = false;
                Aereturnvalue.Rowdata = MainEntity;
                AskUser.PopupConfirmationMessage("Saved.");

                barEditItem1.EditValue = null;
                barStaticItem1.Caption = "Saved.";
                btnsave.Enabled = false;
                btncancel.Enabled = false;
                btnclose.Enabled = true;
                btnedit.Enabled = true;
                FmMode = ENumFmMode.View;
                MethodAllowEdit(false);

            } catch (Exception ex){
                MessageBox.Show(ex.Message);
            }


        }

        protected virtual void MainEntityBackgroundSaveDoWork(object sender, DoWorkEventArgs e){
            

        }

        protected virtual void MethodLoadControlValuesToObjectsForSaving(){
            //todo
        }

        protected virtual bool MethodValidate(){
            throw new NotImplementedException();
        }

        private void BtncancelItemClick(object sender,DevExpress.XtraBars.ItemClickEventArgs e){
            dxErrorProvider1.ClearErrors();
            switch (FmMode){
                case ENumFmMode.New:
                    MethodNewEntityProcedure();
                    break;
                case ENumFmMode.View:
                    throw new ArgumentOutOfRangeException();
                case ENumFmMode.Edit:
                    MethodAllowEdit(false);
                    MethodDispayMainEntityToControls();
                    break;
                case ENumFmMode.Delete:
                    throw new NotImplementedException();
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
        private void BtncloseItemClick(object sender,DevExpress.XtraBars.ItemClickEventArgs e){
            Close();
        }

        protected virtual void MethodAllowEdit(bool allowedit){
        if (DesignMode) return;
            if (allowedit){
                btnedit.Enabled = false;
                btnsave.Enabled = true;
                btncancel.Enabled = true;
                MethodDisableControls(false);
                return;
            }
            btnedit.Enabled = true;
            btncancel.Enabled = false;
            btnsave.Enabled = false;
            MethodDisableControls(true);

            return;
        }

        private void MethodDisableControls(bool disable){
        if (DesignMode) return;
            if (disable){
                for (int index = 0; index < this.layoutControl1.Controls.Count; index++){
                    var control = this.layoutControl1.Controls[index];
                    if (!control.GetType().IsSubclassOf(typeof (BaseEdit))) continue;
                    BaseEdit be = (BaseEdit) control;
                    if (_aeUseReadOnlyPropertyWhenLocking) be.Properties.ReadOnly = true;
                    else be.Enabled = true;
                }
            } else{
                for (int index = 0; index < this.layoutControl1.Controls.Count; index++){
                    var control = this.layoutControl1.Controls[index];
                    if (!control.GetType().IsSubclassOf(typeof (BaseEdit))) continue;
                    BaseEdit be = (BaseEdit) control;
                    if (control.Name.Contains("_ro_")){
                        if (_aeUseReadOnlyPropertyWhenLocking) be.Properties.ReadOnly = true;
                        else be.Enabled = true;
                    } else if (control.Name.Contains("_pk_") & FmMode == ENumFmMode.Edit){
                        if (_aeUseReadOnlyPropertyWhenLocking) be.Properties.ReadOnly = true;
                        else be.Enabled = true;
                    } else{
                        if (_aeUseReadOnlyPropertyWhenLocking) be.Properties.ReadOnly = false;
                        else be.Enabled = false;

                    }
                    if (control.Name.Contains("fcs1")){
                        control.Focus();
                    }
                }
            }
        }
        private void MethodView(bool fetchLookupTables = false, bool fetchMainEntity = true){
        if (DesignMode) return;
            btncancel.Enabled = false;
            MethodAllowEdit(false);
            barEditItem1.EditValue = Properties.Resources.facebookindicator;
            barStaticItem1.Caption = "Loading...";
            BackgroundWorker bgw = new BackgroundWorker();
            bgw.WorkerReportsProgress = true;
            bgw.DoWork += MainEntityBackgroundFetchDoWork;
            bgw.RunWorkerCompleted += MainEntityFetchComplete;
            bgw.ProgressChanged += MainEntityFetchProgressChanged;
            FetchParam fetchParam = new FetchParam();
            fetchParam.PkMode = AeUsePkCode;
            fetchParam.PkCode = Pkcode;
            fetchParam.PkId = Pkid;
            fetchParam.Cs = Cs;
            fetchParam.FetchLookupTables = fetchLookupTables;
            fetchParam.FetchMainEntity = fetchMainEntity;

            bgw.RunWorkerAsync(fetchParam);
        }
        private void MethodViewforEdit(){
        if (DesignMode) return;
            MethodAllowEdit(false);
            barEditItem1.EditValue = Properties.Resources.facebookindicator;
            barStaticItem1.Caption = "Loading...";
            BackgroundWorker bgw = new BackgroundWorker();
            bgw.WorkerReportsProgress = true;
            bgw.DoWork += MainEntityBackgroundFetchDoWork;
            bgw.RunWorkerCompleted += MainEntityFetchComplete;
            bgw.ProgressChanged += MainEntityFetchProgressChanged;
            FetchParam fetchParam = new FetchParam();
            fetchParam.PkMode = AeUsePkCode;
            fetchParam.PkCode = Pkcode;
            fetchParam.PkId = Pkid;
            fetchParam.Cs = Cs;
            bgw.RunWorkerAsync(fetchParam);
        }
        protected virtual void MethodClearForm(){
        if (DesignMode) return;
              for (int index = 0; index < this.layoutControl1.Controls.Count; index++){
                    var control = this.layoutControl1.Controls[index];
                    if (!control.GetType().IsSubclassOf(typeof (BaseEdit))) continue;
                    BaseEdit be = (BaseEdit) control;
                  if (be.Name.Contains("_ae_")){
                      be.EditValue = null;
                  }
                    
                }
        }

        protected virtual void MethodDispayMainEntityToControls(){
            //todo
            MethodClearForm();
        }
        
        protected virtual void MainEntityFetchProgressChanged(object sender, ProgressChangedEventArgs e){
             if (IsDisposed){
                 ((BackgroundWorker) sender).Dispose();
                 return;
             }
             
         }
        protected virtual void MainEntityFetchComplete(object sender, RunWorkerCompletedEventArgs e){
            try{
                if (this.IsDisposed) return;
                if (this.Disposing) return;
                if (e.Cancelled) return;

                if (e.Error != null){
                    string userMessage = ErrorHandler.GetUserMessage(e.Error);
                    AskUser.PopupSystemError(userMessage);
                    return;
                }

                if (e.Result == null) return;
                FetchParam fetchresult = (FetchParam) e.Result;
                if (fetchresult.FetchMainEntity){
                    MainEntity = fetchresult.MainEntityFetched;                   
                    MethodDispayMainEntityToControls();
                    if (FmMode == ENumFmMode.Edit | FmMode == ENumFmMode.New){
                        btnedit.Enabled = true;
                        btncancel.Enabled = true;
                    }

                }
                
            } catch (Exception ex){
                MessageBox.Show(ex.Message);
            } finally{
                barEditItem1.EditValue = null;
                barStaticItem1.Caption = null;
                BackgroundWorker bg = (BackgroundWorker) sender;
                bg.Dispose();
            }
        }
        protected virtual void MainEntityBackgroundFetchDoWork(object sender, DoWorkEventArgs e){
            //todo
        }
        //Todo
    }

    public class FetchParam{
        public bool PkMode;
        public string PkCode;
        public int PkId;
        public string Cs;
        public bool FetchLookupTables;
        public bool FetchMainEntity;
        public object MainEntityFetched;
    }

//End class
} // End namespace